home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Classes / ScrollingTextField / ScrollTextField_Example / ScrollTextField.m < prev    next >
Encoding:
Text File  |  1992-07-23  |  7.4 KB  |  412 lines

  1.  
  2. /* Generated by Interface Builder */
  3. // Uncopyrighted by Eric Celeste, 1991 <efc@mit.edu>
  4.  
  5. #import "ScrollTextField.h"
  6. #import <stdlib.h>
  7.  
  8. @implementation ScrollTextField
  9.  
  10. //
  11. // BIRTH, DEATH, & REBIRTH
  12. //
  13. - initFrame:(NXRect *)frameRect
  14.  {
  15.     NXRect rect = {0.0, 0.0, 0.0, 0.0};
  16.  
  17.     [super initFrame:frameRect];
  18.     
  19.     /*    Set up the text and attach it to the docView.
  20.     */
  21.     [self getContentSize:&(rect.size)];
  22.     myText = [self newText:&rect];
  23.     [self setDocView:myText];
  24.     [myText setSel:0 :0];    
  25.     
  26.     /*    This new filter is needed so that we can end editing with tabs
  27.         but let returns go into the text. The NXEditorFilter() does not
  28.         end on either, and the NXFieldFilter() ends on both. See
  29.         ScrollingTextFilter() for more details. We make ourselves the
  30.         delegate to take care of movement, see TextDidEnd:endChar: for
  31.         more details.
  32.     */
  33.     [myText setCharFilter:(NXCharFilterFunc)ScrollingTextFilter];
  34.     [myText setDelegate:self];
  35.     
  36.     /*    The following two lines allow the resizing of the scrollview
  37.         to be passed down to the docView (in this case, the text view 
  38.         itself).
  39.     */
  40.     [contentView setAutoresizeSubviews:YES];
  41.     [contentView setAutosizing:NX_HEIGHTSIZABLE | NX_WIDTHSIZABLE];
  42.     
  43.     /*    Set the instance variables and other important attributes.
  44.         These are done late in the initFrame so that the text will
  45.         already be properly set up for those operation which effect
  46.         the text (in myText).
  47.     */
  48.     [[self setVertScrollerRequired:YES] setHorizScrollerRequired:NO];
  49.     [self setBackgroundGray:NX_WHITE];
  50.     [self setTextGray:NX_BLACK];
  51.     [self setBorderType:NX_BEZEL];
  52.     [self setSelectable:YES];
  53.     [self setEditable:YES];
  54.     [self setMonofont:YES];
  55.     
  56.     /*    Allocate memory for myString so that we can safely free
  57.         it in the future.
  58.     */
  59.     myString = (char *)malloc(1);
  60.     
  61.     return self;
  62.  }
  63.  
  64. - awake
  65.  {
  66.      [super awake];
  67.     
  68.     /*    This new filter is needed so that we can end editing with tabs
  69.         but let returns go into the text. The NXEditorFilter() does not
  70.         end on either, and the NXFieldFilter() ends on both. See
  71.         ScrollingTextFilter() for more details. We make ourselves the
  72.         delegate to take care of movement, see TextDidEnd:endChar: for
  73.         more details.
  74.     */
  75.     [myText setCharFilter:(NXCharFilterFunc)ScrollingTextFilter];
  76.     [myText setDelegate:self];
  77.     
  78.     return self;
  79.  }
  80.  
  81. - newText:(const NXRect *)frameRect
  82.  {
  83.     id    text;
  84.     NXSize aSize = {1.0E38, 1.0E38};    // very big!
  85.     
  86.     text = [[Text alloc] 
  87.                 initFrame:frameRect
  88.                 text:NULL
  89.                 alignment:NX_LEFTALIGNED
  90.     ];
  91.     
  92.     [text setOpaque:YES];
  93.     
  94.     [[[[[text
  95.             notifyAncestorWhenFrameChanged:YES]
  96.             setVertResizable:YES]
  97.             setHorizResizable:NO]
  98.             setMonoFont:NO]
  99.             setDelegate:self
  100.     ];
  101.     
  102.     [text setMinSize:&(frameRect->size)];
  103.     [text setMaxSize:&aSize];
  104.     [text setAutosizing:NX_HEIGHTSIZABLE | NX_WIDTHSIZABLE];
  105.     
  106.     [text setCharFilter:NXEditorFilter];
  107.     return text;
  108.  }
  109.  
  110. - (const char *)inspectorName
  111.  {
  112.     return "ScrollTextFieldInspector";
  113.  }
  114.  
  115. - free
  116.  {
  117.      free(myString);
  118.      [super free];
  119.     return self;
  120.  }
  121. - read:(NXTypedStream*)stream
  122.  {
  123.     [super read:stream];
  124.     NXReadTypes(stream,"ffiiii*@@@@", 
  125.         &bgGray, &txtGray, 
  126.         &border, &selectable, &editable, &monofont,
  127.         &myString,
  128.         &myText, &previousText,
  129.         &nextText, &textDelegate
  130.     );
  131.     return self;
  132.  }
  133.  
  134. - write:(NXTypedStream*)stream
  135.  {
  136.     [super write:stream];
  137.     NXWriteTypes(stream,"ffiiii*@@@@", 
  138.         &bgGray, &txtGray, 
  139.         &border, &selectable, &editable, &monofont,
  140.         &myString,
  141.         &myText, &previousText,
  142.         &nextText, &textDelegate
  143.     );
  144.     return self;
  145.  }
  146.  
  147. //
  148. // INSTANCE VARIABLES
  149. //
  150. - setBackgroundGray:(float)g
  151.  {
  152.     [myText setBackgroundGray:(bgGray = g)];
  153.     [self display];
  154.     return self;
  155.  }
  156.  
  157. - (float)backgroundGray
  158.  {
  159.     return bgGray;
  160.  }
  161.  
  162.  
  163. - setTextGray:(float)g
  164.  {
  165.     [myText setTextGray:(txtGray = g)];
  166.     [self display];
  167.     return self;
  168.  }
  169.  
  170. - (float)textGray
  171.  {
  172.     return txtGray;
  173.  }
  174.  
  175.  
  176. - setBorderType:(int)x
  177.  {
  178.     [super setBorderType:(border = x)];
  179.     return self;
  180.  }
  181.  
  182. - (int)borderType
  183.  {
  184.     return border;
  185.  }
  186.  
  187. - setSelectable:(BOOL)x
  188.  {
  189.     [myText setSelectable:(selectable = x)];
  190.     return self;
  191.  }
  192.  
  193. - (BOOL)isSelectable
  194.  {
  195.     return selectable;
  196.  }
  197.  
  198. - setEditable:(BOOL)x
  199.  {
  200.     [myText setEditable:(editable = x)];
  201.     return self;
  202.  }
  203.  
  204. - (BOOL)isEditable
  205.  {
  206.     return editable;
  207.  }
  208.  
  209. - setMonofont:(BOOL)x
  210.  {
  211.     [myText setMonoFont:(monofont = x)];
  212.     return self;
  213.  }
  214.  
  215. - (BOOL)isMonofont
  216.  {
  217.     return monofont;
  218.  }
  219.  
  220. - setTag:(int)anInt
  221.  {
  222.     // Makes anInt the Text object's tag
  223.     [myText setTag:anInt];
  224.     return self;
  225.  }
  226.  
  227. - (int)tag
  228.  {
  229.     // Returns the Text object's tag
  230.     return [myText tag];
  231.  }
  232.  
  233. - setPreviousText:anObject;
  234.  {
  235.      previousText = anObject;
  236.     return self;
  237.  }
  238.  
  239. - setNextText:anObject
  240.  {
  241.      nextText = anObject;
  242.     [nextText setPreviousText:self];
  243.     return self;
  244.  }
  245.  
  246. //
  247. // DOCVIEW TEXT
  248. //
  249. - setStringValue:(const char *)string
  250.  {
  251.      [myText setText:string];
  252.     return self;
  253.  }
  254.  
  255. - (const char *)stringValue;
  256.  {
  257.      int length;
  258.     
  259.      free(myString);
  260.     myString = (char *)malloc((length = [myText textLength])+1);
  261.     [myText getSubstring:myString start:0 length:length];
  262.     myString[length] = '\0';
  263.     return (const char *)myString;
  264.  }
  265.  
  266. - selectText:sender
  267.  {
  268.      [myText selectText:self];
  269.     return self;
  270.  }
  271.  
  272. //
  273. // TEXT DELEGATE DUTIES
  274. //
  275. - textDidEnd:sender endChar:(unsigned short)whyEnd
  276.  { 
  277.     if (textDelegate) {
  278.         if ([textDelegate respondsTo:@selector(textDidEnd:endChar:)]) {
  279.             [textDelegate textDidEnd:sender endChar:whyEnd];
  280.         }
  281.     }    
  282.     
  283.     switch (whyEnd) { 
  284.     case NX_RETURN:  
  285.         /* this should never happen because of the filter set */
  286.         break; 
  287.     case NX_TAB:  
  288.         /* make the next text object the first responder */
  289.         if (nextText) {
  290.             [nextText selectText:self];
  291.         } else {
  292.             [self selectText:self];
  293.         }
  294.         break; 
  295.     case NX_BACKTAB:  
  296.         /* make the previous text object the first responder */ 
  297.         if (previousText) {
  298.             [previousText selectText:self];
  299.         } else {
  300.             [self selectText:self];
  301.         }
  302.         break; 
  303.     }
  304.     
  305.     return self;
  306.  }
  307.  
  308. - (BOOL)textWillEnd:textObject
  309.  { 
  310.     if (textDelegate) {
  311.         if ([textDelegate respondsTo:@selector(textWillEnd:)]) {
  312.             return [textDelegate textWillEnd:textObject];
  313.         }
  314.     }    
  315.     
  316.     return NO;
  317.  }
  318.  
  319. - (BOOL)textWillChange:textObject;
  320.  { 
  321.     if (editable) {
  322.         if (textDelegate) {
  323.             if ([textDelegate respondsTo:@selector(textWillChange:)]) {
  324.                 return [textDelegate textWillChange:textObject];
  325.             }
  326.         }
  327.         return NO;
  328.     }
  329.     
  330.     return YES;    
  331.  }
  332.  
  333. - textDidChange:textObject;
  334.  { 
  335.     if (textDelegate) {
  336.         if ([textDelegate respondsTo:@selector(textDidChange:)]) {
  337.             [textDelegate textDidChange:textObject];
  338.         }
  339.     }    
  340.     
  341.     return self;
  342.  }
  343.  
  344. - textDidGetKeys:textObject isEmpty:(BOOL)flag;
  345.  { 
  346.     if (textDelegate) {
  347.         if ([textDelegate respondsTo:@selector(textDidGetKeys:isEmpty:)]) {
  348.             [textDelegate textDidGetKeys:textObject isEmpty:flag];
  349.         }
  350.     }    
  351.     
  352.     return self;
  353.  }
  354.  
  355. //
  356. // UTILITIES
  357. //
  358. unsigned short ScrollingTextFilter(unsigned short theChar, int flags)
  359.  { 
  360.      if (flags & NX_COMMANDMASK) {
  361.          return (NX_ILLEGAL);
  362.      }
  363.     
  364.     if (flags & NX_NUMERICPADMASK) {
  365.         switch (theChar) {
  366.             case 172: return (NX_LEFT);
  367.             case 173: return (NX_UP);
  368.             case 174: return (NX_RIGHT);
  369.             case 175: return (NX_DOWN);
  370.         }
  371.     }
  372.     
  373.     switch (theChar) {
  374.         case NX_DELETE:
  375.                 return (NX_BACKSPACE);
  376.         case NX_CR:
  377.                 return ('\n');
  378.         case NX_BTAB:
  379.                 return (NX_BACKTAB);
  380.         case '\t':
  381.                 return ((flags & NX_SHIFTMASK) ? NX_BACKTAB : NX_TAB);
  382.     }
  383.     
  384.     return ((theChar < ' ') ? NX_ILLEGAL : theChar);
  385.  }
  386.  
  387. //
  388. // TARGET-ACTION
  389. //
  390. /* --------------------------- comment out begins -------------
  391. - setTarget:(id)anObject
  392.  {
  393.     target = anObject;
  394.     return self;
  395.  }
  396.  
  397. - setAction:(SEL)aSelector
  398.  {
  399.     action = aSelector;
  400.     return self;
  401.  }
  402.  
  403. - takeStringValueFrom:sender
  404.  {
  405.     return self;
  406.  }
  407.  
  408. --------------------------- comment out begins -------------*/
  409. // END
  410.  
  411. @end
  412.